package com.log4jviewer.logfile;

import java.text.ParseException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.log4jviewer.logfile.fields.AbstractField;
import com.log4jviewer.logfile.fields.LogFieldName;
import com.log4jviewer.logfile.fields.LogLevelName;

/**
 * Class creates log records using specified record pattern.
 * 
 * @author <a href="mailto:rd.ryly@gmail.com">Ruslan Diachenko</a>
 */
public class LogRecordCreator {

    private Pattern recordPattern;

    private List<AbstractField> logFields;

    public LogRecordCreator(final Pattern recordPattern, final List<AbstractField> logFields) {
        this.recordPattern = recordPattern;
        this.logFields = logFields;
    }

    public LogRecord createLogRecord(final String content) throws ParseException {
        Matcher patternMatcher = recordPattern.matcher(content);
        LogRecord logRecord = null;

        if (patternMatcher.find()) {
            logRecord = new LogRecord();

            for (int i = 0; i < logFields.size(); i++) {
                String value = patternMatcher.group(i + 1).trim();
                AbstractField logField = logFields.get(i);
                LogFieldName fieldName = logField.getLogFieldName();
                Object fieldValue = logField.decodeValue(value);

                switch (fieldName) {
                case CATEGORY:
                    logRecord.setCategoryName((String) fieldValue);
                    break;
                case CLASS:
                    logRecord.setClassName((String) fieldValue);
                    break;
                case DATE:
                    logRecord.setDate((String) fieldValue);
                    break;
                case FILE:
                    logRecord.setFileName((String) fieldValue);
                    break;
                case LINE:
                    logRecord.setLineNumber((Integer) fieldValue);
                    break;
                case MESSAGE:
                    logRecord.setMessage((String) fieldValue);
                    break;
                case METHOD:
                    logRecord.setMethodName((String) fieldValue);
                    break;
                case LEVEL:
                    logRecord.setLevel((LogLevelName) fieldValue);
                    break;
                case MILLISECONDS:
                    logRecord.setMilliseconds((Integer) fieldValue);
                    break;
                case THREAD:
                    logRecord.setThreadName((String) fieldValue);
                    break;
                case NDC:
                    logRecord.setNdc((String) fieldValue);
                    break;
                case MDC:
                    logRecord.setMdc((String) fieldValue);
                    break;
                default: // no code
                }
            }
        }
        return logRecord;
    }
}
